Automating tasks is one of the best ways to keep a system running smoothly. If you take
all the repetitive system administration commands you need to run regularly and have them
run in background without your direct involvement, system administration becomes much less
onerous and bothersome. The utilities cron and at were developed to help make your job
easier. Both allow you to execute commands automatically at specified times, without
bothering you.
The cron (short for chronograph) utility is designed to allow commands to execute at
specific times without anyone directly initiating them. Linux loads cron as a clock daemon
when the system starts up. (The cron utility is usually run from an rc file entry; you can
disable it by commenting out the line that starts cron.) When operating, cron reads the
days and times it is supposed to execute a task from a file called the crontab file.
Whenever one of the crontab file's day and time specification entries matches the
system's date and time, the cron daemon executes the command. The cron utility doesn't
just execute the task once; the task is run again whenever the specified day and time
match the system day and time. The task continues to be run until you terminate the cron
utility or modify the crontab file. The automatic execution of tasks means that cron is
ideal for automating regular system administration tasks such as tape backups, database
reorganization, and general file cleanups (such as emptying log files and queues).
On most systems, access to cron is limited to the system administrator, although you
can easily activate it for some or all users on your system. System administrators control
who can send processes to be executed by cron through one of two different files, often
called /usr/lib/cron/cron.allow or /usr/lib/cron/cron.deny. Many Linux systems use the
names /etc/cron.d/cron.allow and /etc/cron.d/cron.deny. Both files have one username
(which matches the entry in /etc/passwd) per line.
The file /usr/lib/cron/cron.allow (or /etc/cron.d/cron.allow) can contain a list of all
usernames that are allowed to use cron. For example, the file
tparker yvonne bill
allows only the logins tparker, yvonne, and bill (as well as the superuser) to submit
anything to cron.
The file /usr/lib/cron/cron.deny can contain a list of usernames that are not allowed
to use cron. For example, the file
walter anne
allows everyone except the logins walter and anne to use cron.
By using one of these optional files, system administrators can control cron usage. If
neither the cron.allow or cron.deny files exist, only the superuser (root) can submit
processes to cron. To allow all users to use cron, create an empty cron.deny file.
To instruct cron to process commands at particular days and times, you use a utility
called crontab. The crontab program reads a file that contains the details of what you
want cron to do and queues it. In addition, crontab performs several other administrative
tasks, such as displaying your current cron task list, removing the list, and adding new
tasks to the list.
The file that crontab reads to determine what you want to submit to cron is usually
named crontab for convenience, although you can call it anything. The crontab utility has
a command option that allows you to specify the filenameyou want it to use. If you don't
use this option, the crontab utility reads the default filename, crontab.
The crontab instruction file has a simple structure. The file consists of one complete
line for each process to be submitted that specifies when to run the process and what
command to execute. The format of each line is as follows:
minute hour day-of-month month-of-year day-of-week command
An example two-line extract from a crontab file looks like the following:
20 1 * * * /usr/bin/calendar - 0 2 * * * /bin/organize_data
Each line in the crontab file has six columns separated by whitespace (spaces or tabs).
The columns, from left to right are as follows:
This rather strange (at first glance) format is necessary to enable you to completely
specify when a process is to run. Without the five different categories for days and time,
you couldn't uniquely specify any event that occurs one or more times a month. These
columns are quite easy to complete.
The last column contains the command or script filename that is to be executed. A
script that is to be executed can have many lines and call other scripts, or it can be
only a single line. The first process is initiated when the crontab file matches the day
and time. It is important to provide an absolute pathname to the command (even if it's in
your PATH), as the cron jobs do not inherit your environment variables and thus don't know
where to look for commands. Also, you must have execute permission for the utility or
script. If you are submitting crontab files as a user (not superuser), you must have file
permissions or ownership set to allow you normal access, as cron executes the processes as
though you owned them.
Each time and day column in the crontab file can contain a single number anywhere in
the range of valid numbers, two numbers separated by a minus sign to show an inclusive
range (such as 1-5 to show one through five), a list of numbers separated by commas to
mean all of the values explicitly specified, or an asterisk meaning all legal values.
Look at the following sample lines of a crontab file to see how this file works:
20 1 * * * /usr/bin/calendar - 0 2 1 * 0 /bin/organize_data 10,30,50 9-18 * * * /bin/setperms
This example specifies three different processes. The first command is
/usr/bin/calendar - (the hyphen is an important part of the command). This process is
executed at 20 minutes past one in the morning (cron uses a 24-hour clock) every day of
the week and each day of the year. The asterisks mean all values(every day).
At 2:00AM, a script file called /bin/organize_data is executed on the first day of
every month (the 1 in the third column) and every Sunday (the 0 in the fifth column). If
the first day is a Sunday, it executes only once, of course. The third line shows that a
script called /bin/setperms runs at 10, 30, and 50 minutes past the hour every hour
between 9:00AM and 6:00PM (18:00), every day of the week.
The entries in a crontab file do not have to be in any special order. As long as each
entry is on a line by itself and has all six fields specified properly, cron organizes the
information for its own use. If you have an error in the crontab file, cron mails you a
notice of the problem when it processes your file. (This notice can be annoying if you
have the entry with the error set to execute often because cron mails you each time it
tries to execute the entry and finds a problem. Your mailbox quickly gets filled with cron
error messages.)
Keep the crontab files in your home directory and name them crontab, unless you want to
have several versions of the files, in which case you can use any naming convention you
want. Keeping the names simple helps you identify which file you want cron to execute.
After you write your crontab file, you can submit it for cron to execute. When you
submit a crontab file, a copy of the file is made and kept in a cron directory, usually
/usr/spool/cron/crontabs. The file has the name of the submitting user. A crontab file
submitted by yvonne, for example, has the name /usr/spool/cron/crontabs/yvonne. Any
crontab files submitted by the superuser usually have the name root.
To submit your crontab file to cron, use the crontab command followed by the name of
the file with the cron commands in it. For example, the command
crontab crontab
submits the file called crontab in the current directory to cron. If you had previously
submitted a cron file, it is removed and the new file is used instead.
Always submit a change to cron using the crontab file and an edited ASCII file. Never make changes to the file in /usr/spool/cron/crontabs; the changes will not be read by cron and can potentially mess up any existing cron tasks.
You can see what you have submitted to cron by using the -l (list) option. This option
shows all the crontab entries the cron utility knows about (essentially displaying the
contents of the file with your username from /usr/spool/cron/crontabs). For example, the
command
crontab -l
shows all cron tasks for the user who submits the command.
To remove your crontab file and not replace it, it use the -r (remove) option. This
option erases the file with your filename from the /usr/spool/cron/crontabs directory. The
syntax for this command is as follows:
crontab -r
Finally, you can call up your current cron file and start an editor (the default editor
as defined by your environment variables or a system default variable) by using the -e
(editor) option. When you issue the command
crontab -e
crontab reads your existing crontab file and loads it into the default editor (such as
vi). When you save the edited file, it is submitted to cron automatically.
Changes to the crontab file are usually effective within five minutes at most, as cron
reads the contents of the /usr/spool/cron/crontab file at least once every five minutes
and often more frequently (most Linux systems have cron check the directories every
minute). Because you have to wait for cron to check the contents of the crontab file,
execution of a process you have submitted to cron can sometimes be delayed by a few
minutes, so don't rely on cron to be exactly on time. The more heavily loaded a system is,
the greater the delay in execution.
On some systems, system administrators can log all cron usage by modifying an entry in
the file /etc/default/cron. One line in the file should contain the variable CRONLOG. If
you set the value equal to YES, cron logs every action it takes to the file
/usr/lib/cron/log. Not all versions of Linux allow cron logging. If you do enable cron
logging, check the log file frequently as it can grow to a large size quite quickly.
The crontab file can contain any type of command or shell script, as long as the line
is valid (in other words, it could be executed from the shell prompt). A common problem
with many shell commands is the generation of output, especially error messages, which is
mailed to you and can clog up your mailbox quickly. For this reason, if you anticipate
error message output (from a compiler, for example), you can redirect the output to
/dev/null. For example, the command
0 * * * * date > /tmp/test1 2>/dev/null
sends the output of the date command to a file called /tmp/test1 every hour and sends
any error messages to /dev/null (which essentially discards such messages). You can do the
same with the standard output, if you want, or you can redirect it elsewhere. For example,
the cron command
30 1 * * * cat /usr/tparker/chapt* > /usr/tparker/archive/backup
concatenates all the files starting with chapt in /usr/tparker into one large file
called /usr/tparker/archive/backup. Again, you can redirect the the standard output.
You can also do piping in the crontab file. For example, if you have a list of users
who are logged in the system during the day in the file /tmp/userlist, you can have a
crontab entry that looks like the following:
0 1 * * * sort -u /tmp/userlist | mail -s"users for today" root
This line sorts the output of /tmp/userlist so that there is only one entry for each
user (the -u or unique option) and mails it to root.
An important point to remember with cron is that all commands are executed, by default,
in the Bourne shell (or bash, if it is the sh equivalent on your system). If you use C
shell commands, the cron task will fail.
The at program is very similar to cron, except that at executes a command only once at
a prespecified time and cron keeps executing a command. The format of the at command is as
follows:
at time date < file
You can specify most of the at command parameters in several different ways, which
makes the at command versatile. you can specify the time, for example, as an absolute time
(18:40 or 22:00) or as two digits that are taken as hours (so 10 means ten o'clock in the
morning as a 24-hour clock is the default). You can add an am or pm to the time to make it
clear which you mean, so 10pm is unambiguously in the evening.
The at command handles a few special words instead of time designations. The command
recognizes the words noon, midnight, now, next, and zulu for GMT conversion. (Some at
versions generate an error message if you try to execute a command with the time set to
now.)
The date is an optional field that you use when the time is not specific enough. If you
don't supply a date, at executes the command the next time the specified time occurs. If
you specify a date, at waits until that date to execute the command. You can give the date
as a month's name followed by a day number (May 10) or a day of the week (either spelled
out in full or abbreviated to three characters). You also can specify a year, but this
specification is seldom necessary. As with the time, the at command recognizes two special
words that relate to dates: today and tomorrow (although the word today is redundant as
the command executes today by default if the time is set properly).
The file to be read in as input to the at command can be any file with commands in it.
Alternatively, you can type in the commands and press Ctrl+d when you're finished,
although this method is not recommended due to the high potential for error.
Suppose you have a file called reorg.data with the following commands in it:
/usr/tparker/setperms /usr/tparker/sort_database /usr/tparker/index_database /usr/tparker/clean_up
If you want to execute this file at 8:30PM, issue any one of the following commands:
at 20:30 < reorg.data at 8:30 pm < reorg/data at 20:30 today < reorg.data
Even more variations are possible, but you can see the syntax. If you want to execute
the command on Friday, issue the command in one of these formats:
at 8:30 pm Friday < reorg.data at 20:30 Fri < reorg.data
Some versions of at are even more talented and handle special words. For example, this
command
at 0900 Monday next week < reorg.data
executes the commands next week on a Monday. Not all versions of at can handle these
complex formats, however. Check the man pages to see which formats your version supports,
or just try these formats and see whether you get an error message.
When you submit a program to at for execution, you get back a job identification
number. This number uniquely identifies the at command you just issued. For example, look
at the output from this at command:
$ at 6 < do_it job 827362.a at Wed Aug 31 06:00:00 EDT 1995
In this case, the job ID is 827362.a and the ID is needed to make any changes to the
job.
You can list all the jobs you have queued with at using the -l (list) option. The
output usually tells you when the command is set to execute, but not what the command is:
$ at -l user = tparker job 827362.a at Wed Aug 31 06:00:00 EDT 1995 user = tparker job 829283.a at Wed Aug 31 09:30:00 EDT 1995
Some versions of Linux may support the shorter form of the command with atq (display
the at queue). If you get an error message when you issue the atq command, you have to use
the at -l format.
To remove an at job from the system, you need the job ID and the at -r (remove)
command. For example, the command
at -r 2892732.a
removes the specified job. Linux doesn't return any message to indicate the job has
been canceled, but you will see the job is gone if you list the queue. You can remove only
your own jobs (root can remove any). Some Linux versions support the atrm command as well
as the -r option.
All jobs that are queued to at are kept in the directory /usr/spool/cron/atjobs with
the job ID number as the filename. As with cron, an at.allow and an at.deny file in either
the /usr/lib/cron or /etc/cron.d directory controls who can and can't use at. As with
cron, create an empty at.deny file if you want all users on your system to be able to use
at.
When an at job executes, all output (standard output and error messages) is mailed back
to the username who submitted the job unless it has been redirected. The at command
retains all the environment variables and directory settings of the user. If you look at a
queued job in /usr/spool/cron/atjobs, you see all the variables defined prior to the
command to be executed.
As you have seen, cron and at are quite easy to use. They are also a system
administrator's best friends, as you can automate tiresome tasks like cleaning up
databases, checking disk space, flushing log files, and making tape backups with cron or
at. Although cron and at can't do everything for you, they can handle repetitive tasks
with ease.
Most Linux systems have a number of sample cron files supplied with the operating system. Examine those files (or list the current crontab file while logged in as root) to see what the operating system wants to execute on a regular basis. Use those commands as the starting point and add your own commands. Probably the worst that can happen if you mess up a crontab file is that you will get a lot of mail!